package com.ics.cmsadmin.modules.basic.service.impl;

import com.ics.cmsadmin.frame.core.enums.ApiResultEnum;
import com.ics.cmsadmin.modules.basic.bean.ProblemDto;
import com.ics.cmsadmin.modules.basic.bean.ProblemSetBean;
import com.ics.cmsadmin.modules.basic.bean.ProblemSetDto;
import com.ics.cmsadmin.modules.basic.bean.ScoreBean;
import com.ics.cmsadmin.modules.basic.dao.ProblemSetDao;
import com.ics.cmsadmin.frame.core.annotation.CacheDbMember;
import com.ics.cmsadmin.frame.core.enums.CacheGroupEnum;
import com.ics.cmsadmin.frame.core.annotation.ClearDbMember;
import com.ics.cmsadmin.frame.core.enums.LevelTypeEnum;
import com.ics.cmsadmin.frame.core.exception.CmsException;
import com.ics.cmsadmin.frame.core.bean.PageBean;
import com.ics.cmsadmin.frame.core.bean.PageResult;
import com.ics.cmsadmin.modules.basic.service.ProblemService;
import com.ics.cmsadmin.modules.basic.service.ProblemSetService;
import com.ics.cmsadmin.modules.basic.service.SubjectService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

/**
 * Created by lvsw on 2018-09-06.
 */
@Service
public class ProblemSetServiceImpl implements ProblemSetService {
    @Resource
    private ProblemSetDao problemSetDao;
    @Resource
    private SubjectService subjectService;
    @Resource
    private ProblemService problemService;

    @CacheDbMember(returnClass = ProblemSetBean.class, group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public ProblemSetBean queryById(String id) {
        if (StringUtils.isBlank(id)){
            return null;
        }
        ProblemSetBean problemSetBean = problemSetDao.queryById(id);
        Optional.ofNullable(problemSetBean)
            .ifPresent(item -> item.setLevelNodeName(subjectService.findNameByLevelNode(item.getLevelNode())));
        return problemSetBean;
    }

    @CacheDbMember(returnClass = ProblemSetBean.class, group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public PageResult<ProblemSetBean> list(ProblemSetBean bean, PageBean page) {
        long count = problemSetDao.count(bean);
        if (count == 0){
            return new PageResult<>();
        }
        page = page == null ? new PageBean() : page;
        List<ProblemSetBean> list = problemSetDao.list(bean, page);
        Optional.ofNullable(list)
            .ifPresent(items -> {
                items.stream().forEach(item -> item.setLevelNodeName(subjectService.findNameByLevelNode(item.getLevelNode())));
            });
        return PageResult.getPage(count, list);
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public boolean insert(ProblemSetBean bean) {
        if (bean == null){
            return false;
        }
        String[] split = bean.getLevelNode().split(",");
        Integer level = Integer.valueOf(bean.getLevel());
        if (split.length - 1 != Integer.valueOf(bean.getLevel())) {
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "类型节点和类型不一致");
        }
        LevelTypeEnum levelTypeEnum = LevelTypeEnum.vauleByIndex(level);
        if (levelTypeEnum == null){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "类型上传有误");
        }
        bean.setLevel(levelTypeEnum.getTypeName());
        bean.setLevelId(split[split.length - 1]);
        return problemSetDao.insert(bean) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public boolean update(String id, ProblemSetBean bean) {
        if (StringUtils.isBlank(id) || bean == null || queryById(id) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "参数有误");
        }

        // 要么一起levelNode 和 level 一起不为空
        if (StringUtils.isNotBlank(bean.getLevelNode()) && StringUtils.isNotBlank(bean.getLevel())){
            String[] split = bean.getLevelNode().split(",");
            Integer level = Integer.valueOf(bean.getLevel());
            if (split.length - 1 != Integer.valueOf(bean.getLevel())) {
                throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "类型节点和类型不一致");
            }
            LevelTypeEnum levelTypeEnum = LevelTypeEnum.vauleByIndex(level);
            if (levelTypeEnum == null){
                throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "类型上传有误");
            }
            bean.setLevel(levelTypeEnum.getTypeName());
            bean.setLevelId(split[split.length - 1]);
        }else if (!(StringUtils.isBlank(bean.getLevelNode()) && StringUtils.isBlank(bean.getLevel()))){ // 要么一起levelNode 和 level 不同时有值
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "类型节点和类型不一致");
        }

        return problemSetDao.update(id, bean) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public boolean delete(String id) {
        throw new CmsException(ApiResultEnum.DELETE_TABLE_ITEM_FAIL, "题集不支持删除功能");
    }

    @CacheDbMember(returnClass = ProblemSetBean.class, group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public ProblemSetBean queryByProblemId(String problemId) {
        return problemSetDao.queryByProblemId(problemId);
    }

    @CacheDbMember(returnClass = ProblemSetDto.class, group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public ProblemSetDto findProblemSetDetails(ProblemSetBean problemSetBean) {
        ProblemSetBean one = problemSetDao.findOne(problemSetBean);
        if (one == null){
            return null;
        }
        List<ProblemDto> problemDtos = problemService.queryDetailsByProblemSetId(one.getProblemSetId());
        return ProblemSetDto.builder().problemSet(one).problems(problemDtos).build();
    }

    @Override
    public boolean submitScore(ScoreBean scoreBean) {
        if (scoreBean == null){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "参数为空");
        }
        if(queryById(scoreBean.getProblemSetId()) == null){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "题集不存在");
        }
        problemSetDao.mergeIntoScore(scoreBean);
        return true;
    }
}
